package com.coderysh.rabbitmq.util;

import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.ConnectionFactory;

import java.io.IOException;
import java.util.concurrent.TimeoutException;

/**
 * @author 姚书恒
 * @version 1.0
 * @email yaoshuheng@zjkeyou.com
 * @date 2021-10-26 15:08:00
 * @description: 工具类
 */
public class RabbitmqUtil {
    private static ConnectionFactory FACTORY;

    static {
        String host = "192.168.30.88";
        int port = 5672;
        String virtualHost = "/ysh";
        String username = "admin";
        String password = "adminysh";
        initFactory(host, port, virtualHost, username, password);
    }

    /**
     * 初始化工厂
     */
    private static void initFactory(String host, int port, String virtualHost, String username, String password) {
        if (null == FACTORY) {
            FACTORY = new ConnectionFactory();
        }
        // 设置连接mq主机
        FACTORY.setHost(host);
        // 设置端口
        FACTORY.setPort(port);
        // 设置连接虚拟主机
        FACTORY.setVirtualHost(virtualHost);
        // 设置访问虚拟主机的用户名和密码
        FACTORY.setUsername(username);
        FACTORY.setPassword(password);
    }

    /**
     * 获取连接
     *
     * @return
     */
    public static Connection connection() {
        // 获取连接对象
        Connection connection = null;
        try {
            connection = FACTORY.newConnection();
        } catch (IOException e) {
            e.printStackTrace();
        } catch (TimeoutException e) {
            e.printStackTrace();
        }
        return connection;
    }

    /**
     * 创建通道
     */
    public static Channel createChannel(Connection connection) {
        if (null == connection) {
            return null;
        }
        // 获取连接中通道
        Channel channel = null;
        try {
            channel = connection.createChannel();
        } catch (IOException e) {
            e.printStackTrace();
            return null;
        }
        return channel;
    }

    /**
     * 通道绑定对应的消息队列
     *
     * @param channel 通道
     */
    public void queueDeclare(Channel channel) {
        // 通道绑定对应的消息队列
        // 参数1：队列名称，不存在时会自动创建
        // 参数2：定义队列的特性，是否要持久化，true代表持久化（当mq服务关闭时，会存到磁盘中，下次重启会不会丢失）队列，false代表不持久化
        // 参数3：是否独占队列，true代表独占队列，相对于本次连接而言，为true则只能通过本次连接进行操作；false代表不独占，可被其他连接操作
        // 参数4：是否在消费完成后自动删除队列，true 自动删除，false不自动删除
        // 参数5：额外付加参数
        try {
            channel.queueDeclare("hello", false, false, false, null);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * 发布消息
     *
     * @param channel
     * @param message
     * @return
     */
    public boolean publishMessage(Channel channel, String message) {
        // 发布消息
        // 参数1：交换机名称，没有可以不设置
        // 参数2：队列名称
        // 参数3：传递消息的额外设置
        // 参数4：消息的具体内容
        try {
            channel.basicPublish("", "hello", null, message.getBytes());
        } catch (IOException e) {
            e.printStackTrace();
            return false;
        }
        return true;
    }

    /**
     * 关闭通道
     *
     * @param channel
     */
    public static void closeChannel(Channel channel) {
        try {
            channel.close();
        } catch (IOException e) {
            e.printStackTrace();
        } catch (TimeoutException e) {
            e.printStackTrace();
        }
    }

    /**
     * 关闭连接
     *
     * @param connection
     */
    public static void closeConnection(Connection connection) {
        try {
            connection.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}
